package net.dipper.tankwar.game.ui;

import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import wnb.util.control.Command;
import wnb.util.control.CommandEngine;

import net.dipper.tankwar.core.config.ConfigManager;
import net.dipper.tankwar.core.data.ObjectMap;
import net.dipper.tankwar.core.helper.Position;
import net.dipper.tankwar.core.helper.ViewPort;
import net.dipper.tankwar.game.control.GameControl;
import net.dipper.tankwar.game.control.GameRule;

public class GameContext {
	public static final int VIEWPORT_WIDTH = 20;
	public static final int VIEWPORT_HEIGHT = 20;
	public static final byte STATUS_READY = 0;
	public static final byte STATUS_RUNNING = 1;
	public static final byte STATUS_PAUSED = 2;
	public static final byte STATUS_STOPED = 3;
	private ObjectMap map;
	private ViewPort viewPort;
	private GameControl control;
	private GameRule rule;
	private CommandEngine engine;
	private ArrayList<GameContextListener> listeners;
	private byte status;	//状态
	
	public GameContext(ObjectMap map){
		try{
			ConfigManager.getInstance();
			this.map = map;
			this.engine = new CommandEngine();
			this.rule = new GameRule(this, map, engine);
			this.control = new GameControl(this, map);
			this.listeners = new ArrayList<GameContextListener>();
			
			int width = map.getWidth();
			int height = map.getHeight();
			Position p = map.getPlayer();
			int x = p.x - VIEWPORT_WIDTH / 2;
			int y = p.y - VIEWPORT_HEIGHT / 2;
			
			if(x < 0){
				x = 0;
			}else if(x > width - VIEWPORT_WIDTH){
				x = width - VIEWPORT_WIDTH;
			}		
			if(y < 0){
				y = 0;
			}else if(y > height - VIEWPORT_HEIGHT){
				y = height - VIEWPORT_HEIGHT;
			}
			
			this.viewPort = new ViewPort(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
		}catch(IOException | ClassNotFoundException | InstantiationException | IllegalAccessException | ParserConfigurationException | SAXException ex){
			ex.printStackTrace();
		}
	}

	public ObjectMap getMap(){
		return this.map;
	}

	public ViewPort getViewPort() {
		return new ViewPort(viewPort.x, viewPort.y, viewPort.width, viewPort.height);
	}
	
	//开启游戏运行系统
	public void start() {
		this.rule.start();
		engine.start();
		this.status = STATUS_RUNNING;
		notifyListeners(this.status);
	}

	//设置视域
	public void resetViewPort() {
		Position player = map.getPlayer();
		int posX = player.x - this.viewPort.width / 2 ;
		int posY = player.y - this.viewPort.height / 2;
		if(posX < 0)
			posX = 0;
		if(posY < 0)
			posY = 0;
		if(posX + this.viewPort.width > map.getWidth())
			posX = map.getWidth() - this.viewPort.width;
		if(posY + this.viewPort.height > map.getHeight())
			posY = map.getHeight() - this.viewPort.height;
		
		this.viewPort.x = posX;
		this.viewPort.y = posY;
	}

	//获取是否已暂停
	public boolean getIsPaused() {
		return this.engine.getIsPaused();
	}

	//恢复运行
	public void resume() {
		this.engine.resume();
		this.status = STATUS_RUNNING;
		notifyListeners(this.status);
	}

	//暂停运行
	public void pause() {
		this.engine.pause();
		this.status = STATUS_PAUSED;
		notifyListeners(this.status);
	}

	public GameControl getControl() {
		return this.control;
	}
	
	public void pushCommand(Command command){
		this.engine.addCommand(command);
	}

	//停止运行
	public void stop() {
		this.engine.stop();
		this.status = STATUS_STOPED;
		notifyListeners(this.status);
	}

	//添加监听器
	public void addListener(GameContextListener listener){
		this.listeners.add(listener);
	}

	//通知监听器
	public void notifyListeners(byte status){
		for(GameContextListener listener : listeners){
			listener.onGameContextStatusChanged(this, status);
		}
	}
}
